/*
 * @(#)TMSchema.java 5/17/2011
 *
 * Copyright 2002 - 2011 JIDE Software Inc. All rights reserved.
 */

package com.element.plaf.windows;

import sun.awt.windows.ThemeReader;

import javax.swing.*;
import java.awt.*;
import java.util.EnumMap;

/**
 * Implements Windows Parts and their States and Properties for the Windows Look and Feel.
 * <p/>
 * See http://msdn.microsoft.com/library/default.asp?url=/library/en-us/shellcc/platform/commctls/userex/topics/partsandstates.asp
 * See tmschema.h (or vssym32.h & vsstyle.h for MS Vista)
 * <p>
 * Copied from JDK source code and modified to provide additional integration between JIDE components and native windows L&F.
 *
 * @author Leif Samuelsson
 */
public class TMSchema {

	/**
	 * An enumeration of the various Windows controls (also known as components, or top-level parts)
	 */
	public enum Control {
		BUTTON,
		COMBOBOX,
		EDIT,
		HEADER,
		LISTBOX,
		LISTVIEW,
		MENU,
		PROGRESS,
		REBAR,
		SCROLLBAR,
		SPIN,
		TAB,
		TOOLBAR,
		TRACKBAR,
		TREEVIEW,
		WINDOW,
		EXPLORERBAR
	}


	/**
	 * An enumeration of the Windows compoent parts
	 */
	public enum Part {
		MENU(Control.MENU, 0), // Special case, not in native
		MP_BARBACKGROUND(Control.MENU, 7),
		MP_BARITEM(Control.MENU, 8),
		MP_POPUPBACKGROUND(Control.MENU, 9),
		MP_POPUPBORDERS(Control.MENU, 10),
		MP_POPUPCHECK(Control.MENU, 11),
		MP_POPUPCHECKBACKGROUND(Control.MENU, 12),
		MP_POPUPGUTTER(Control.MENU, 13),
		MP_POPUPITEM(Control.MENU, 14),
		MP_POPUPSEPARATOR(Control.MENU, 15),
		MP_POPUPSUBMENU(Control.MENU, 16),

		BP_PUSHBUTTON(Control.BUTTON, 1),
		BP_RADIOBUTTON(Control.BUTTON, 2),
		BP_CHECKBOX(Control.BUTTON, 3),
		BP_GROUPBOX(Control.BUTTON, 4),
		BP_COMMANDLINK(Control.BUTTON, 6),
		BP_COMMANDLINKGLYPH(Control.BUTTON, 7),

		CP_COMBOBOX(Control.COMBOBOX, 0),
		CP_DROPDOWNBUTTON(Control.COMBOBOX, 1),
		CP_BACKGROUND(Control.COMBOBOX, 2),
		CP_TRANSPARENTBACKGROUND(Control.COMBOBOX, 3),
		CP_BORDER(Control.COMBOBOX, 4),
		CP_READONLY(Control.COMBOBOX, 5),
		CP_DROPDOWNBUTTONRIGHT(Control.COMBOBOX, 6),
		CP_DROPDOWNBUTTONLEFT(Control.COMBOBOX, 7),
		CP_CUEBANNER(Control.COMBOBOX, 8),


		EP_EDIT(Control.EDIT, 0),
		EP_EDITTEXT(Control.EDIT, 1),

		HP_HEADERITEM(Control.HEADER, 1),
		HP_HEADERITEMLEFT(Control.HEADER, 2),
		HP_HEADERITEMRIGHT(Control.HEADER, 3),
		HP_HEADERSORTARROW(Control.HEADER, 4),
		HP_HEADERDROPDOWN(Control.HEADER, 5),
		HP_HEADERDROPDOWNFILTER(Control.HEADER, 6),
		HP_HEADEROVERFLOW(Control.HEADER, 7),

		LBP_LISTBOX(Control.LISTBOX, 0),

		LVP_LISTVIEW(Control.LISTVIEW, 0),

		PP_PROGRESS(Control.PROGRESS, 0),
		PP_BAR(Control.PROGRESS, 1),
		PP_BARVERT(Control.PROGRESS, 2),
		PP_CHUNK(Control.PROGRESS, 3),
		PP_CHUNKVERT(Control.PROGRESS, 4),

		RP_GRIPPER(Control.REBAR, 1),
		RP_GRIPPERVERT(Control.REBAR, 2),

		SBP_SCROLLBAR(Control.SCROLLBAR, 0),
		SBP_ARROWBTN(Control.SCROLLBAR, 1),
		SBP_THUMBBTNHORZ(Control.SCROLLBAR, 2),
		SBP_THUMBBTNVERT(Control.SCROLLBAR, 3),
		SBP_LOWERTRACKHORZ(Control.SCROLLBAR, 4),
		SBP_UPPERTRACKHORZ(Control.SCROLLBAR, 5),
		SBP_LOWERTRACKVERT(Control.SCROLLBAR, 6),
		SBP_UPPERTRACKVERT(Control.SCROLLBAR, 7),
		SBP_GRIPPERHORZ(Control.SCROLLBAR, 8),
		SBP_GRIPPERVERT(Control.SCROLLBAR, 9),
		SBP_SIZEBOX(Control.SCROLLBAR, 10),

		SPNP_UP(Control.SPIN, 1),
		SPNP_DOWN(Control.SPIN, 2),

		TABP_TABITEM(Control.TAB, 1),
		TABP_TABITEMLEFTEDGE(Control.TAB, 2),
		TABP_TABITEMRIGHTEDGE(Control.TAB, 3),
		TABP_PANE(Control.TAB, 9),

		TP_TOOLBAR(Control.TOOLBAR, 0),
		TP_BUTTON(Control.TOOLBAR, 1),
		TP_DROPDOWNBUTTON(Control.TOOLBAR, 2),
		TP_SPLITBUTTON(Control.TOOLBAR, 3),
		TP_SPLITBUTTONDROPDOWN(Control.TOOLBAR, 4),
		TP_SEPARATOR(Control.TOOLBAR, 5),
		TP_SEPARATORVERT(Control.TOOLBAR, 6),
		TP_DROPDOWNBUTTONGLYPH(Control.TOOLBAR, 7),

		TKP_TRACK(Control.TRACKBAR, 1),
		TKP_TRACKVERT(Control.TRACKBAR, 2),
		TKP_THUMB(Control.TRACKBAR, 3),
		TKP_THUMBBOTTOM(Control.TRACKBAR, 4),
		TKP_THUMBTOP(Control.TRACKBAR, 5),
		TKP_THUMBVERT(Control.TRACKBAR, 6),
		TKP_THUMBLEFT(Control.TRACKBAR, 7),
		TKP_THUMBRIGHT(Control.TRACKBAR, 8),
		TKP_TICS(Control.TRACKBAR, 9),
		TKP_TICSVERT(Control.TRACKBAR, 10),

		TVP_TREEVIEW(Control.TREEVIEW, 0),
		TVP_GLYPH(Control.TREEVIEW, 2),

		WP_WINDOW(Control.WINDOW, 0),
		WP_CAPTION(Control.WINDOW, 1),
		WP_MINCAPTION(Control.WINDOW, 3),
		WP_MAXCAPTION(Control.WINDOW, 5),
		WP_FRAMELEFT(Control.WINDOW, 7),
		WP_FRAMERIGHT(Control.WINDOW, 8),
		WP_FRAMEBOTTOM(Control.WINDOW, 9),
		WP_SYSBUTTON(Control.WINDOW, 13),
		WP_MDISYSBUTTON(Control.WINDOW, 14),
		WP_MINBUTTON(Control.WINDOW, 15),
		WP_MDIMINBUTTON(Control.WINDOW, 16),
		WP_MAXBUTTON(Control.WINDOW, 17),
		WP_CLOSEBUTTON(Control.WINDOW, 18),
		WP_MDICLOSEBUTTON(Control.WINDOW, 20),
		WP_RESTOREBUTTON(Control.WINDOW, 21),
		WP_MDIRESTOREBUTTON(Control.WINDOW, 22),

		EBP_EXPLORERBAR(Control.EXPLORERBAR, 0),
		EBP_HEADERBACKGROUND(Control.EXPLORERBAR, 1),
		EBP_HEADERCLOSE(Control.EXPLORERBAR, 2),
		EBP_HEADERPIN(Control.EXPLORERBAR, 3),
		EBP_IEBARMENU(Control.EXPLORERBAR, 4),
		EBP_NORMALGROUPBACKGROUND(Control.EXPLORERBAR, 5),
		EBP_NORMALGROUPCOLLAPSE(Control.EXPLORERBAR, 6),
		EBP_NORMALGROUPEXPAND(Control.EXPLORERBAR, 7),
		EBP_NORMALGROUPHEAD(Control.EXPLORERBAR, 8),
		EBP_SPECIALGROUPBACKGROUND(Control.EXPLORERBAR, 9),
		EBP_SPECIALGROUPCOLLAPSE(Control.EXPLORERBAR, 10),
		EBP_SPECIALGROUPEXPAND(Control.EXPLORERBAR, 11),
		EBP_SPECIALGROUPHEAD(Control.EXPLORERBAR, 12),
		;

		private final Control control;
		private final int value;

		Part(Control control, int value) {
			this.control = control;
			this.value = value;
		}

		public int getValue() {
			return value;
		}

		public String getControlName(Component component) {
			String str = "";
			if (component instanceof JComponent c) {
				String subAppName = (String) c.getClientProperty("XPStyle.subAppName");
				if (subAppName != null) {
					str = subAppName + "::";
				}
			}
			return str + control.toString();
		}

		public String toString() {
			return control.toString() + "." + name();
		}
	}


	/**
	 * An enumeration of the possible component states
	 */
	public enum State {
		ACTIVE,
		ASSIST,
		BITMAP,
		CHECKED,
		CHECKEDDISABLED,
		CHECKEDHOT,
		CHECKEDNORMAL,
		CHECKEDPRESSED,
		CHECKMARKNORMAL,
		CHECKMARKDISABLED,
		BULLETNORMAL,
		BULLETDISABLED,
		CLOSED,
		DEFAULTED,
		DISABLED,
		DISABLEDHOT,
		DISABLEDPUSHED,
		DOWNDISABLED,
		DOWNHOT,
		DOWNNORMAL,
		DOWNPRESSED,
		FOCUSED,
		HOT,
		HOTCHECKED,
		NEARHOT,
		OTHERSIDEHOT,
		ICONHOT,
		ICONNORMAL,
		ICONPRESSED,
		ICONSORTEDHOT,
		ICONSORTEDNORMAL,
		ICONSORTEDPRESSED,
		INACTIVE,
		INACTIVENORMAL,         // See note 1
		INACTIVEHOT,            // See note 1
		INACTIVEPUSHED,         // See note 1
		INACTIVEDISABLED,       // See note 1
		LEFTDISABLED,
		LEFTHOT,
		LEFTNORMAL,
		LEFTPRESSED,
		MIXEDDISABLED,
		MIXEDHOT,
		MIXEDNORMAL,
		MIXEDPRESSED,
		IMPLICITDISABLED,
		IMPLICITHOT,
		IMPLICITNORMAL,
		IMPLICITPRESSED,
		EXCLUDEDDISABLED,
		EXCLUDEDHOT,
		EXCLUDEDNORMAL,
		EXCLUDEDPRESSED,
		NORMAL,
		PRESSED,
		OPENED,
		PUSHED,
		READONLY,
		RIGHTDISABLED,
		RIGHTHOT,
		RIGHTNORMAL,
		RIGHTPRESSED,
		SELECTED,
		UNCHECKEDDISABLED,
		UNCHECKEDHOT,
		UNCHECKEDNORMAL,
		UNCHECKEDPRESSED,
		UPDISABLED,
		UPHOT,
		UPNORMAL,
		UPPRESSED,
		HOVER,
		UPHOVER,
		DOWNHOVER,
		LEFTHOVER,
		RIGHTHOVER,
		SORTEDDOWN,
		SORTEDHOT,
		SORTEDNORMAL,
		SORTEDPRESSED,
		SORTEDUP,
		SOFTHOT,
		DEFAULTED_ANIMATING;


		/**
		 * A map of allowed states for each Part
		 */
		private static EnumMap<Part, State[]> stateMap;

		private static synchronized void initStates() {
			stateMap = new EnumMap<>(Part.class);

			stateMap.put(Part.EP_EDITTEXT,
					new State[]{
							NORMAL, HOT, SELECTED, DISABLED, FOCUSED, READONLY, ASSIST
					});

			stateMap.put(Part.BP_PUSHBUTTON,
					new State[]{NORMAL, HOT, PRESSED, DISABLED, DEFAULTED, DEFAULTED_ANIMATING});

			stateMap.put(Part.BP_RADIOBUTTON,
					new State[]{
							UNCHECKEDNORMAL, UNCHECKEDHOT, UNCHECKEDPRESSED, UNCHECKEDDISABLED,
							CHECKEDNORMAL, CHECKEDHOT, CHECKEDPRESSED, CHECKEDDISABLED
					});

			stateMap.put(Part.BP_CHECKBOX,
					new State[]{
							UNCHECKEDNORMAL, UNCHECKEDHOT, UNCHECKEDPRESSED, UNCHECKEDDISABLED,
							CHECKEDNORMAL, CHECKEDHOT, CHECKEDPRESSED, CHECKEDDISABLED,
							MIXEDNORMAL, MIXEDHOT, MIXEDPRESSED, MIXEDDISABLED,
							IMPLICITNORMAL, IMPLICITHOT, IMPLICITPRESSED, IMPLICITDISABLED,
							EXCLUDEDNORMAL, EXCLUDEDHOT, EXCLUDEDPRESSED, EXCLUDEDDISABLED
					});

			stateMap.put(Part.BP_COMMANDLINK,
					new State[]{
							DEFAULTED, DEFAULTED_ANIMATING, DISABLED, HOT, NORMAL, PRESSED
					});

			stateMap.put(Part.BP_COMMANDLINKGLYPH,
					new State[]{
							DEFAULTED, DISABLED, HOT, NORMAL, PRESSED
					});

			State[] comboBoxStates = new State[]{NORMAL, HOT, PRESSED, DISABLED};
			stateMap.put(Part.CP_COMBOBOX, comboBoxStates);
			stateMap.put(Part.CP_DROPDOWNBUTTON, comboBoxStates);
			stateMap.put(Part.CP_BACKGROUND, comboBoxStates);
			stateMap.put(Part.CP_TRANSPARENTBACKGROUND, comboBoxStates);
			stateMap.put(Part.CP_BORDER, comboBoxStates);
			stateMap.put(Part.CP_READONLY, comboBoxStates);
			stateMap.put(Part.CP_DROPDOWNBUTTONRIGHT, comboBoxStates);
			stateMap.put(Part.CP_DROPDOWNBUTTONLEFT, comboBoxStates);
			stateMap.put(Part.CP_CUEBANNER, comboBoxStates);

			stateMap.put(Part.HP_HEADERITEM, new State[]{NORMAL, HOT, PRESSED,
					SORTEDNORMAL, SORTEDHOT, SORTEDPRESSED,
					ICONNORMAL, ICONHOT, ICONPRESSED,
					ICONSORTEDNORMAL, ICONSORTEDHOT, ICONSORTEDPRESSED});

			stateMap.put(Part.HP_HEADERSORTARROW,
					new State[]{SORTEDDOWN, SORTEDUP});

			stateMap.put(Part.HP_HEADERDROPDOWN,
					new State[]{NORMAL, SOFTHOT, HOT});

			stateMap.put(Part.HP_HEADERDROPDOWNFILTER,
					new State[]{NORMAL, SOFTHOT, HOT});

			stateMap.put(Part.HP_HEADEROVERFLOW,
					new State[]{NORMAL, HOT});

			State[] scrollBarStates = new State[]{NORMAL, HOT, PRESSED, DISABLED, HOVER};
			stateMap.put(Part.SBP_SCROLLBAR, scrollBarStates);
			stateMap.put(Part.SBP_THUMBBTNVERT, scrollBarStates);
			stateMap.put(Part.SBP_THUMBBTNHORZ, scrollBarStates);
			stateMap.put(Part.SBP_GRIPPERVERT, scrollBarStates);
			stateMap.put(Part.SBP_GRIPPERHORZ, scrollBarStates);

			stateMap.put(Part.SBP_ARROWBTN,
					new State[]{
							UPNORMAL, UPHOT, UPPRESSED, UPDISABLED,
							DOWNNORMAL, DOWNHOT, DOWNPRESSED, DOWNDISABLED,
							LEFTNORMAL, LEFTHOT, LEFTPRESSED, LEFTDISABLED,
							RIGHTNORMAL, RIGHTHOT, RIGHTPRESSED, RIGHTDISABLED,
							UPHOVER, DOWNHOVER, LEFTHOVER, RIGHTHOVER
					});


			State[] spinnerStates = new State[]{NORMAL, HOT, PRESSED, DISABLED};
			stateMap.put(Part.SPNP_UP, spinnerStates);
			stateMap.put(Part.SPNP_DOWN, spinnerStates);

			stateMap.put(Part.TVP_GLYPH, new State[]{CLOSED, OPENED});

			State[] frameButtonStates = new State[]{
					NORMAL, HOT, PUSHED, DISABLED,  // See note 1
					INACTIVENORMAL, INACTIVEHOT, INACTIVEPUSHED, INACTIVEDISABLED,
			};
			// Note 1: The INACTIVE frame button states apply when the frame
			//         is inactive. They are not defined in tmschema.h

			// Fix for 6316538: Vista has five frame button states
			if (ThemeReader.getInt(Control.WINDOW.toString(),
					Part.WP_CLOSEBUTTON.getValue(), 1,
					Prop.IMAGECOUNT.getValue()) == 10) {
				frameButtonStates = new State[]{
						NORMAL, HOT, PUSHED, DISABLED, null,
						INACTIVENORMAL, INACTIVEHOT, INACTIVEPUSHED, INACTIVEDISABLED, null
				};
			}

			stateMap.put(Part.WP_MINBUTTON, frameButtonStates);
			stateMap.put(Part.WP_MAXBUTTON, frameButtonStates);
			stateMap.put(Part.WP_RESTOREBUTTON, frameButtonStates);
			stateMap.put(Part.WP_CLOSEBUTTON, frameButtonStates);

			// States for Slider (trackbar)
			stateMap.put(Part.TKP_TRACK, new State[]{NORMAL});
			stateMap.put(Part.TKP_TRACKVERT, new State[]{NORMAL});

			State[] sliderThumbStates =
					new State[]{NORMAL, HOT, PRESSED, FOCUSED, DISABLED};
			stateMap.put(Part.TKP_THUMB, sliderThumbStates);
			stateMap.put(Part.TKP_THUMBBOTTOM, sliderThumbStates);
			stateMap.put(Part.TKP_THUMBTOP, sliderThumbStates);
			stateMap.put(Part.TKP_THUMBVERT, sliderThumbStates);
			stateMap.put(Part.TKP_THUMBRIGHT, sliderThumbStates);

			// States for Tabs
			State[] tabStates = new State[]{NORMAL, HOT, SELECTED, DISABLED, FOCUSED};
			stateMap.put(Part.TABP_TABITEM, tabStates);
			stateMap.put(Part.TABP_TABITEMLEFTEDGE, tabStates);
			stateMap.put(Part.TABP_TABITEMRIGHTEDGE, tabStates);


			stateMap.put(Part.TP_BUTTON,
					new State[]{
							NORMAL, HOT, PRESSED, DISABLED, CHECKED, HOTCHECKED
					});

			State[] buttonStates = {
					NORMAL, HOT, PRESSED, DISABLED, CHECKED, HOTCHECKED, NEARHOT, OTHERSIDEHOT
			};
			stateMap.put(Part.TP_DROPDOWNBUTTON, buttonStates);

			stateMap.put(Part.TP_SPLITBUTTON, buttonStates);

			stateMap.put(Part.TP_SPLITBUTTONDROPDOWN, buttonStates);

			stateMap.put(Part.TP_DROPDOWNBUTTONGLYPH, buttonStates);

			State[] frameStates = new State[]{ACTIVE, INACTIVE};
			stateMap.put(Part.WP_WINDOW, frameStates);
			stateMap.put(Part.WP_FRAMELEFT, frameStates);
			stateMap.put(Part.WP_FRAMERIGHT, frameStates);
			stateMap.put(Part.WP_FRAMEBOTTOM, frameStates);

			State[] captionStates = new State[]{ACTIVE, INACTIVE, DISABLED};
			stateMap.put(Part.WP_CAPTION, captionStates);
			stateMap.put(Part.WP_MINCAPTION, captionStates);
			stateMap.put(Part.WP_MAXCAPTION, captionStates);

			stateMap.put(Part.MP_BARBACKGROUND,
					new State[]{ACTIVE, INACTIVE});
			stateMap.put(Part.MP_BARITEM,
					new State[]{NORMAL, HOT, PUSHED,
							DISABLED, DISABLEDHOT, DISABLEDPUSHED});
			stateMap.put(Part.MP_POPUPCHECK,
					new State[]{CHECKMARKNORMAL, CHECKMARKDISABLED,
							BULLETNORMAL, BULLETDISABLED});
			stateMap.put(Part.MP_POPUPCHECKBACKGROUND,
					new State[]{DISABLEDPUSHED, NORMAL, BITMAP});
			stateMap.put(Part.MP_POPUPITEM,
					new State[]{NORMAL, HOT, DISABLED, DISABLEDHOT});
			stateMap.put(Part.MP_POPUPSUBMENU,
					new State[]{NORMAL, DISABLED});

			State[] headerStates = {
					NORMAL, HOT, PRESSED
			};

			stateMap.put(Part.EBP_HEADERCLOSE, headerStates);

			stateMap.put(Part.EBP_HEADERPIN, new State[]{
					NORMAL, HOT, PRESSED, CHECKED, CHECKEDHOT, CHECKEDPRESSED
			});

			stateMap.put(Part.EBP_IEBARMENU, headerStates);
			stateMap.put(Part.EBP_NORMALGROUPCOLLAPSE, headerStates);
			stateMap.put(Part.EBP_NORMALGROUPEXPAND, headerStates);
			stateMap.put(Part.EBP_SPECIALGROUPCOLLAPSE, headerStates);
			stateMap.put(Part.EBP_SPECIALGROUPEXPAND, headerStates);
		}


		public static synchronized Enum[] getState(Part part) {
			if (stateMap == null) {
				initStates();
			}

			return stateMap.get(part);
		}

		public static synchronized int getValue(Part part, State state) {
			if (stateMap == null) {
				initStates();
			}

			Enum[] states = stateMap.get(part);
			if (states != null) {
				for (int i = 0; i < states.length; i++) {
					if (state == states[i]) {
						return i + 1;
					}
				}
			}

			if (state == null || state == State.NORMAL) {
				return 1;
			}

			return 0;
		}

	}


	/**
	 * An enumeration of the possible component attributes and the corresponding value type
	 */
	public enum Prop {
		COLOR(Color.class, 204),
		SIZE(Dimension.class, 207),

		FLATMENUS(Boolean.class, 1001),

		BORDERONLY(Boolean.class, 2203), // only draw the border area of the image

		IMAGECOUNT(Integer.class, 2401), // the number of state images in an imagefile
		BORDERSIZE(Integer.class, 2403), // the size of the border line for bgtype=BorderFill

		PROGRESSCHUNKSIZE(Integer.class, 2411), // size of progress control chunks
		PROGRESSSPACESIZE(Integer.class, 2412), // size of progress control spaces

		TEXTSHADOWOFFSET(Point.class, 3402), // where char shadows are drawn, relative to orig. chars

		NORMALSIZE(Dimension.class, 3409), // size of dest rect that exactly source


		SIZINGMARGINS(Insets.class, 3601), // margins used for 9-grid sizing
		CONTENTMARGINS(Insets.class, 3602), // margins that define where content can be placed
		CAPTIONMARGINS(Insets.class, 3603), // margins that define where caption text can be placed

		BORDERCOLOR(Color.class, 3801), // color of borders for BorderFill
		FILLCOLOR(Color.class, 3802), // color of bg fill
		TEXTCOLOR(Color.class, 3803), // color text is drawn in

		TEXTSHADOWCOLOR(Color.class, 3818), // color of text shadow

		BGTYPE(Integer.class, 4001), // basic drawing type for each part

		TEXTSHADOWTYPE(Integer.class, 4010), // type of shadow to draw with text

		TRANSITIONDURATIONS(Integer.class, 6000);

		private final Class type;
		private final int value;

		Prop(Class type, int value) {
			this.type = type;
			this.value = value;
		}

		public int getValue() {
			return value;
		}

		public String toString() {
			return name() + "[" + type.getName() + "] = " + value;
		}
	}


	/**
	 * An enumeration of attribute values for some Props
	 */
	public enum TypeEnum {
		BT_IMAGEFILE(Prop.BGTYPE, "imagefile", 0),
		BT_BORDERFILL(Prop.BGTYPE, "borderfill", 1),

		TST_NONE(Prop.TEXTSHADOWTYPE, "none", 0),
		TST_SINGLE(Prop.TEXTSHADOWTYPE, "single", 1),
		TST_CONTINUOUS(Prop.TEXTSHADOWTYPE, "continuous", 2);


		TypeEnum(Prop prop, String enumName, int value) {
			this.prop = prop;
			this.enumName = enumName;
			this.value = value;
		}

		private final Prop prop;
		private final String enumName;
		private final int value;

		public String toString() {
			return prop + "=" + enumName + "=" + value;
		}

		String getName() {
			return enumName;
		}


		static TypeEnum getTypeEnum(Prop prop, int enumval) {
			for (TypeEnum e : TypeEnum.values()) {
				if (e.prop == prop && e.value == enumval) {
					return e;
				}
			}
			return null;
		}
	}
}
